<template>
  <div
    class="shop-transcity-add-or-update"
    @click="markClick($event)"
  >
    <el-dialog
      v-model="visible"
      :modal="false"
      :title="$t('shop.chooseDeliveryArea')"
      :close-on-click-modal="false"
    >
      <main
        v-loading="loading"
        element-loading-text="加载中..."
        class="content-box"
      >
        <el-scrollbar style="height:100%;">
          <!-- 区域 -->
          <div
            v-for="region in menuList"
            :key="region.areaId"
            class="addr-region"
          >
            <div class="region-name">
              <el-checkbox
                v-model="region.checked"
                :disabled="region.disabled"
                :indeterminate="region.indeterminate"
                @change="checked=>onRegionChange(checked, region)"
              >
                {{ region.areaName }}
              </el-checkbox>
            </div>
            <div class="province-box">
              <!-- 省 -->
              <div
                v-for="provinceItem in region.areas"
                :key="provinceItem.areaId"
                class="province-item"
              >
                <el-checkbox
                  v-model="provinceItem.checked"
                  :disabled="provinceItem.disabled"
                  :indeterminate="provinceItem.indeterminate"
                  @change="checked=>onRrovinceChange(checked, provinceItem , region)"
                />
                <span
                  style="cursor: pointer;"
                  @click="onHandleProvinceClick(provinceItem)"
                >
                  <span class="check-label">{{ provinceItem.areaName }}</span>
                  <span
                    v-show="provinceItem.show"
                    class="area-count"
                  >({{ provinceItem.areaCount }})</span>
                  <el-icon><ArrowDown /></el-icon>
                </span>
                <!-- 市 -->
                <div
                  v-if="provinceItem.show"
                  class="city-box bor-style"
                >
                  <div
                    v-for="(cityItem,cityIndex) in provinceItem.areas"
                    :key="cityItem.areaId"
                    class="city-item"
                  >
                    <span ref="cityRef">
                      <el-checkbox
                        v-model="cityItem.checked"
                        :disabled="cityItem.disabled"
                        :indeterminate="cityItem.indeterminate"
                        @change="checked=>onCityChange(checked, cityItem , provinceItem,region)"
                      />
                      <span
                        style="cursor: pointer;"
                        @click.stop="onHandleCityClick(provinceItem.areas,cityItem,cityIndex,$event)"
                      >
                        <span
                          class="check-label"
                          :data-inx="cityIndex"
                        >{{ cityItem.areaName }}</span>
                        <span
                          v-show="provinceItem.show"
                          :data-inx="cityIndex"
                          class="area-count"
                        >({{ cityItem.areaCount }})</span>
                        <el-icon :data-inx="cityIndex"><ArrowDown /></el-icon>
                      </span>
                    </span>
                    <!-- 区 -->
                    <div
                      v-show="cityItem.show"
                      ref="areaBoxRef"
                      :style="areaStyle"
                      class="area-box bor-style"
                    >
                      <div
                        v-for="areaItem in cityItem.areas"
                        :key="areaItem.areaId"
                      >
                        <el-checkbox
                          v-model="areaItem.checked"
                          :disabled="areaItem.disabled"
                          @change="checked=>onAreaChange(checked, cityItem ,provinceItem,region)"
                        >
                          {{ areaItem.areaName }}
                        </el-checkbox>
                      </div>
                      <!-- 区小角标 -->
                      <span
                        :style="areaMarkStyle"
                        class="area-mark"
                      />
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div style="height:20px;" />
        </el-scrollbar>
      </main>
      <template #footer>
        <div class="dialog-footer">
          <el-checkbox
            v-model="checkedAllState"
            :indeterminate="checkedAllIndeterminate"
            :disabled="checkedAllDisabled"
            @change="onCheckedAll"
          >
            全选
          </el-checkbox>
          <span>
            <span class="area-num">已选择{{ checkedAreaNum }}个区域</span>
            <div
              class="default-btn primary-btn"
              @click="onSubmit()"
            >{{ $t("crud.filter.submitBtn") }}</div>
          </span>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
const emit = defineEmits(['refreshDataList'])

let type = 0
const visible = ref(false)
const menuList = reactive([])
let rowIndex = 0
// 全选状态
const checkedAllState = ref(false)
// 全选按钮不确定状态
const checkedAllIndeterminate = ref(false)
// 全选按钮是否禁用
const checkedAllDisabled = ref(false)
// 所选区数量
const checkedAreaNum = ref(0)
// 区盒定位样式
const areaStyle = reactive({
  top: '20px',
  left: '20px'
})
// 角标样式
const areaMarkStyle = reactive({
  top: '20px',
  left: '20px'
})

let holdInitData = {}
let tempData = []
const init = (_rowIndex, cityList, allSelectCityList, _type, banArr) => {
  holdInitData = {
    cityList,
    allSelectCityList,
    banArr
  }
  type = _type
  rowIndex = _rowIndex
  checkedAreaNum.value = cityList.length || 0
  if (tempData.length === 0) {
    // 获取所有省和市
    http({
      // url: http.adornUrl('/admin/area/listAreaOfEnable'),
      url: http.adornUrl('/admin/area/areaList'),
      method: 'get',
      params: http.adornParams()
    }).then(({ data }) => {
      tempData = JSON.parse(JSON.stringify(data))
      menuList.splice(0, menuList.length, ...data)
    }).then(() => {
      visible.value = true
    })
  } else {
    visible.value = true
    menuList.splice(0, menuList.length, ...JSON.parse(JSON.stringify(tempData)))
  }
}
const loading = ref(false)
watch(visible, (val) => {
  if (val) {
    loading.value = true
    setTimeout(() => {
      const { cityList, allSelectCityList, banArr } = holdInitData
      disabledNodes(cityList, allSelectCityList, banArr)
    }, 50)
  }
})
defineExpose({ init })

const markClick = (e) => {
  // 点击当前弹窗外的部分关闭展开的列表
  if (e.target.className === 'el-overlay-dialog') {
    handleCheckChange(menuList, { show: false })
  }
}

// 全选
const onCheckedAll = (checked) => {
  if (loading.value) return
  checkedAllIndeterminate.value = false
  handleCheckChange(menuList, { checked, indeterminate: false })
  getAreaCheckedList()
}
// 区域复选框
const onRegionChange = (checked, region) => {
  region.indeterminate = false
  handleCheckChange(region.areas, { checked, indeterminate: false })
  getAreaCheckedList()
  checkedAllJudge() // 放最后
}
// 省复选框
const onRrovinceChange = (checked, province, region) => {
  province.indeterminate = false
  handleCheckChange(province.areas, { checked, indeterminate: false })
  indeterJudge(region)
  getAreaCheckedList()
  checkedAllJudge() // 放最后
}
// 市复选框
const onCityChange = (checked, city, province, region) => {
  city.indeterminate = false
  handleCheckChange(city.areas, { checked })
  indeterJudge(province)
  indeterJudge(region)
  getAreaCheckedList()
  checkedAllJudge() // 放最后
}
// 区复选框
//
// eslint-disable-next-line no-unused-vars
const onAreaChange = (checked, city, province, region) => {
  indeterJudge(city)
  indeterJudge(province)
  indeterJudge(region)
  getAreaCheckedList()
  checkedAllJudge() // 放最后
}
// 检测是否全选
const checkedAllJudge = () => {
  let checkedNum = 0
  let disabledNum = 0
  const len = menuList.length
  let hasIndeterminate = false
  menuList.forEach(region => {
    region.checked && checkedNum++
    region.disabled && disabledNum++
    region.indeterminate && (hasIndeterminate = true)
  })
  // 是否为全选状态
  checkedAllState.value = checkedNum === len
  // 是否为禁用状态
  checkedAllDisabled.value = disabledNum === len
  // 是否为不确定的状态
  checkedAllIndeterminate.value = !(checkedNum === len || checkedNum === 0) || hasIndeterminate
}
// 检测其孩子列表是否全选
const indeterJudge = (parent) => {
  // 选中的个数
  let tCount = 0
  let hasIndeterminate = false
  const len = parent.areas.length
  parent.areas.forEach(item => {
    item.checked && tCount++
    item.indeterminate && (hasIndeterminate = true)
  })
  // 是否选择状态
  parent.checked = tCount === len
  // 是否为不确定的状态
  parent.indeterminate = !(tCount === len || tCount === 0) || hasIndeterminate
}
const handleCheckChange = (list, status) => {
  const { checked, show, indeterminate } = status
  list.forEach(item => {
    show !== undefined && (item.show = show)
    indeterminate !== undefined && (item.indeterminate = indeterminate)
    if (checked !== undefined && !item.disabled) {
      item.checked = checked
    }
    if (item.areas && item.areas.length > 0) {
      handleCheckChange(item.areas, { checked, show, indeterminate })
    }
  })
}
// 获取被选中的区列表
const getAreaCheckedList = () => {
  const resultList = []
  menuList.forEach(region => {
    region.areas.forEach(province => {
      province.areas.forEach(city => {
        city.areas.forEach(area => {
          if (area.checked) {
            resultList.push(area)
          }
        })
      })
    })
  })
  checkedAreaNum.value = resultList.length
  return resultList
}
// 处理省点击
const onHandleProvinceClick = (province) => {
  const flag = province.show
  handleCheckChange(menuList, { show: false })
  province.show = !flag
}
const onHandleCityClick = (cityList, curCity, cityIndex, e) => {
  handleAreaBoxShow(e, cityIndex)
  const flag = curCity.show
  cityList.forEach(item => {
    item.show = false
  })
  curCity.show = !flag
}
// 处理区地址盒子显示
const cityRef = ref(null)
const areaBoxRef = ref(null)
/**
 * 处理区级盒子显示
 * @param {*} e 当前激活节点信息
 * @param {*} index 市列表索引
 */
const handleAreaBoxShow = (e, index) => {
  // 当前点击的节点
  const nodeName = e.target.nodeName.toLowerCase()
  // 市单体所占宽度
  const offsetLeft = cityRef.value[index]?.offsetWidth
  let offsetVal = 0 // 用于计算点击箭头时区块显示的位置
  // 显示区列表的左偏移值
  if (nodeName === 'span') {
    areaStyle.left = e.clientX - e.offsetX + offsetLeft + 14 + 'px'
    areaMarkStyle.left = e.clientX - e.offsetX + offsetLeft + 9 + 'px'
  } else {
    areaStyle.left = e.clientX - e.offsetX + 28 + 'px'
    areaMarkStyle.left = e.clientX - e.offsetX + 23 + 'px'
    offsetVal = -8
  }
  nextTick(() => {
    // 加setTimeout防止有时获取到的高度为0
    setTimeout(() => {
      // 显示区列表盒子的高度
      const areaBoxH = areaBoxRef.value?.[index].offsetHeight
      // 区块上偏移位置
      areaStyle.top = e.clientY - e.offsetY - areaBoxH / 2 + 18 + offsetVal + 'px'
      // 角标
      areaMarkStyle.top = e.clientY - e.offsetY + 12 + offsetVal + 'px'
    })
  })
}
//
// eslint-disable-next-line no-unused-vars
const disabledNodes = (cityList, allSelectCityList, banArr) => {
  let newBanArr = []
  newBanArr = newBanArr.concat(banArr)
  if (newBanArr.length > 0) {
    for (let i = 0; i < newBanArr.length; i++) {
      if (cityList.length > 0) {
        cityList.forEach(item => {
          if (newBanArr[i] === item.areaId) {
            newBanArr.splice(i, 1)
          }
        })
      }
    }
  }

  for (let i = 0; i < menuList.length; i++) {
    let disabledNumOne = 0
    // 状态
    menuList[i].disabled = false
    menuList[i].checked = false
    menuList[i].indeterminate = false

    // 获取所有的省
    const childrenOne = menuList[i].areas
    for (let j = 0; j < childrenOne.length; j++) {
      // 省下区的个数
      let provinceAreaCount = 0
      // debugger
      let disabledNumTwo = 0
      // 状态
      menuList[i].areas[j].disabled = false
      menuList[i].areas[j].show = false
      menuList[i].areas[j].checked = false
      menuList[i].areas[j].indeterminate = false
      // 获取当前省下的所有的市
      const childrenTwo = menuList[i].areas[j].areas
      for (let k = 0; k < childrenTwo.length; k++) {
        // 市下区的个数
        let cityAreaCount = 0
        // 状态
        menuList[i].areas[j].areas[k].disabled = false
        menuList[i].areas[j].areas[k].show = false
        menuList[i].areas[j].areas[k].checked = false
        menuList[i].areas[j].areas[k].indeterminate = false
        if (menuList[i].areas[j].areas[k].areas && menuList[i].areas[j].areas[k].areas.length > 0) {
          let disableChildCity = 0

          // 获取当前市下的所有的区
          const childArea = menuList[i].areas[j].areas[k].areas
          for (let l = 0; l < childArea.length; l++) {
            provinceAreaCount++
            cityAreaCount++
            // 状态
            menuList[i].areas[j].areas[k].areas[l].disabled = false
            const result = cityList.find(cityI => childArea[l].areaId === cityI.areaId)
            // eslint-disable-next-line max-depth
            if (result) {
              menuList[i].areas[j].areas[k].areas[l].checked = true
            } else {
              menuList[i].areas[j].areas[k].areas[l].checked = false
            }
            const banCity = newBanArr.findIndex((item) => item === childArea[l].areaId) > -1
            // eslint-disable-next-line max-depth
            if (banCity) {
              menuList[i].areas[j].areas[k].areas[l].disabled = true
              disableChildCity++
            }
          }
          if (disableChildCity === menuList[i].areas[j].areas[k].areas.length) {
            menuList[i].areas[j].areas[k].disabled = true
            disabledNumTwo++
          }
        }
        // 检测市下的区是否全选
        indeterJudge(menuList[i].areas[j].areas[k])
        // 区个数
        menuList[i].areas[j].areas[k].areaCount = cityAreaCount
      }

      if (disabledNumTwo === menuList[i].areas[j].areas.length) {
        menuList[i].areas[j].disabled = true
        disabledNumOne++
      }
      // 检测省下的市是否全选
      indeterJudge(menuList[i].areas[j])
      // 区个数
      menuList[i].areas[j].areaCount = provinceAreaCount
    }
    if (disabledNumOne === menuList[i].areas.length) {
      menuList[i].disabled = true
    }
    // 检测区域下的省是否全选
    indeterJudge(menuList[i])
  }
  // 判断是否全选
  checkedAllJudge()
  loading.value = false
}
// 表单提交
const onSubmit = () => {
  if (loading.value) return
  const checdNodes = getAreaCheckedList()
  // emit('refreshDataList', rowIndex, menuListTree.getCheckedNodes(true), thisRef.value?.type)
  emit('refreshDataList', rowIndex, checdNodes, type)
  visible.value = false
  handleCheckChange(menuList, { checked: false, show: false })
  // 重置全选按钮状态
  checkedAllState.value = false
  // 全选按钮不确定状态
  checkedAllIndeterminate.value = false
}

</script>

<style lang="scss" scoped>
.content-box{
  height: 500px;

  .check-label{
    padding-left: 8px;
    padding-right: 6px;
    cursor: pointer;
  }

  .addr-region{
    display: flex;
    line-height: 32px;
    margin-bottom: 20px;

    .region-name{
      width: 100px;
    }
    .province-box{
      flex: 1;
      display: flex;
      flex-wrap: wrap;

      .province-item{
        width: 33%;
        position: relative;

        .area-count{
          color: #155bd4;
          padding-right: 6px;
        }

        .bor-style{
          border: 1px solid #eee;
          background-color: #fff;
          border-radius: 2px;
          box-shadow: 0px 0px 3px #ccc;
        }

        .city-box{
          min-width: 70%;
          max-height: calc(32px * 10 + 6px);
          overflow-y: auto;
          overflow-x: hidden;
          padding:3px 12px;
          position: absolute;
          left: -13px;
          z-index: 9;

          .city-item{
            position: relative;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;

            .area-box{
              max-height: calc(32px * 8 + 8px);
              overflow-y: auto;
              overflow-x: hidden;
              padding: 3px 20px;
              line-height: 32px;
              position: fixed;
              background-color: #fff;
              z-index: 999;
            }

            .area-mark{
              // border-left: 1px solid #fff;
              // border-top: 1px solid #fff;
              // border-color: #fff;
              background-color: #fff;
              box-shadow: 1px 1px 3px 0 #ccc;
              display: block;
              width: 10px;
              height: 10px;
              position: fixed;
              transform: rotate(135deg);
            }

          }
        }
      }
    }
  }
}
.dialog-footer{
  display: flex;
  justify-content: space-between;
  align-items: center;
  .area-num{
    margin-right: 12px;
  }
}
.shop-transcity-add-or-update {
  :deep(.el-checkbox__input.is-indeterminate .el-checkbox__inner){
    background-color:#fff;
  }
  :deep(.el-checkbox__input.is-indeterminate .el-checkbox__inner::before){
    background-color:#155bd4;
  }
  :deep(.el-scrollbar__wrap) {
      overflow-x: hidden;
    }
}
</style>
